﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SmartSpace.Core
{
    public partial class CoreService : ICoreService
    {
        public PagedList<Role> GetRoles(int start, int limit)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                List<Role> roles = context.Set<Role>()
                    .OrderByDescending(p => p.CreatedTime)
                    .Skip(start)
                    .Take(limit)
                    .ToList();
                PagedList<Role> pagedRoles = new PagedList<Role>();
                foreach (Role role in roles)
                {
                    pagedRoles.Add(role);
                }
                pagedRoles.Start = start;
                pagedRoles.Limit = limit;
                pagedRoles.Total = context.Set<Role>().Count();

                return pagedRoles;
            }
        }

        public bool SaveRole(Role role)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                if (!EntityRepository.SaveCodeEntity(role, context))
                {
                    return false;
                }
                return EntityRepository.Commit(context);
            }
        }

        public bool DeleteRole(Guid roleId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                if (!EntityRepository.DeleteCodeEntity<Role>(roleId, context))
                {
                    return false;
                }
                return EntityRepository.Commit(context);
            }
        }

        public bool AssignRoleToUser(Role role, User user, bool isMajor)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                UserRoleRelation relation = new UserRoleRelation();
                relation.Id = Guid.NewGuid();
                relation.UserId = user.Id;
                relation.RoleId = role.Id;
                relation.IsMajor = isMajor;

                if (context.Set<UserRoleRelation>().Where(p => p.UserId == user.Id && p.RoleId == role.Id).Select(p => p.Id)
                    .SingleOrDefault() == default(Guid))
                {
                    context.Set<UserRoleRelation>().Add(relation);
                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        public bool RemoveRoleFromUser(Guid roleId, Guid userId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                UserRoleRelation userRole = context.Set<UserRoleRelation>().Where(p => p.UserId == userId && p.RoleId == roleId).SingleOrDefault();

                if (userRole != null)
                {
                    context.Entry(userRole).State = System.Data.Entity.EntityState.Deleted;

                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }
        }

        public bool RemoveRoleFromUser(Guid roleId, string account)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                UserRoleRelation userRole = context.Set<UserRoleRelation>()
                    .Join(context.Set<User>().Where(p=>p.Account == account),
                        l=>l.UserId,
                        r=>r.Id,
                        (l,r)=>l).SingleOrDefault();

                if (userRole != null)
                {
                    context.Entry(userRole).State = System.Data.Entity.EntityState.Deleted;

                    if (context.SaveChanges() > 0)
                    {
                        return true;
                    }
                    return false;
                }
                return true;
            }
        }

        public List<Role> GetRoleListByUser(Guid userId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<UserRoleRelation>().Where(p => p.UserId == userId)
                    .Select(p => p.Role)
                    .OrderBy(p => p.Code)
                    .ToList();
            }
        }

        public List<Role> GetRoleListByUser(string account)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                return context.Set<UserRoleRelation>()
                    .Join(context.Set<User>().Where(p => p.Account == account),
                        l => l.UserId,
                        r => r.Id,
                        (l, r) => l)
                    .Select(p => p.Role)
                    .OrderBy(p => p.Code)
                    .ToList();
            }
        }

        public ServiceResult AssignPrivilegeToRole(Guid privilegeId, Guid roleId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                RolePrivilege rolePrivilege = new RolePrivilege();
                rolePrivilege.RoleId = roleId;
                rolePrivilege.PrivilegeId = privilegeId;
                rolePrivilege.SourceRoleId = roleId;
                rolePrivilege.Type = RolePrivilegeType.Own;

                RolePrivilege existModel = context.Set<RolePrivilege>().Where(p => p.RoleId == roleId && p.PrivilegeId == privilegeId && p.SourceRoleId == roleId).SingleOrDefault();
                if (existModel == null)
                {
                    context.Set<RolePrivilege>().Add(rolePrivilege);
                }

                if (context.SaveChanges() > 0)
                {
                    return new ServiceResult(true, "分配权限成功!");
                }
                return new ServiceResult(false, "分配权限失败!");
            }
        }

        public ListResult<Role> GetParentRoles(Guid roleId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                List<Role> list = context.Set<Role>()
                    .Join(context.Set<RoleRelation>().Where(p => p.RoleId == roleId),
                    r => r.Id,
                    l => l.ParentId,
                    (r, l) => r).ToList();

                return new ListResult<Role>(list);
            }
        }

        public ServiceResult RelateRole(Guid roleId, Guid parentId)
        {
            if (roleId == parentId)
            {
                return new ServiceResult(false, "不能继承自己");
            }

            using (CoreDbContext context = new CoreDbContext())
            {
                RoleRelation existRelation = context.Set<RoleRelation>().Where(p => p.RoleId == parentId && p.ParentId == roleId).SingleOrDefault();
                if (existRelation != null)
                {
                    return new ServiceResult(false, "添加失败，不能循环继承!");
                }

                RoleRelation relation = new RoleRelation();
                relation.RoleId = roleId;
                relation.ParentId = parentId;

                existRelation = context.Set<RoleRelation>().Where(p=>p.RoleId == roleId && p.ParentId == parentId).SingleOrDefault();
                if (existRelation == null)
                {
                    context.Set<RoleRelation>().Add(relation);
                    if (context.SaveChanges() > 0)
                    {
                        return new ServiceResult(true);
                    }
                }
                return new ServiceResult(false);
            }
        }

        public ServiceResult UnRelateRole(Guid roleId, Guid parentId)
        {
            if (roleId == parentId)
            {
                return new ServiceResult(false, "不能继承自己");
            }

            using (CoreDbContext context = new CoreDbContext())
            {
                RoleRelation existRelation = context.Set<RoleRelation>().Where(p => p.RoleId == roleId && p.ParentId == parentId).SingleOrDefault();
                if (existRelation != null)
                {
                    context.Entry(existRelation).State = System.Data.Entity.EntityState.Deleted;
                    if (context.SaveChanges() > 0)
                    {
                        return new ServiceResult(true);
                    }
                    else
                    {
                        return new ServiceResult(false);
                    }
                }
                else
                {
                    return new ServiceResult(true);
                }
            }
        }

        public ListResult<Role> GetRoles(string refModule, Guid refId)
        {
            using (CoreDbContext context = new CoreDbContext())
            {
                List<Role> list = context.Set<Role>().Where(p => p.RefModule == refModule && p.RefId == refId).ToList();
                return new ListResult<Role>(list);
            }
        }
    }
}
